package cz.data.common.mongo;

import com.mongodb.ConnectionString;
import com.mongodb.MongoClientSettings;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import cz.data.common.support.db.DbProperty;
import org.apache.commons.lang3.StringUtils;

import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;

public class CacheMongoClientBean {
    private static final Map<String, MongoClient> CACHE_CCLIENT = new ConcurrentHashMap<>();

    public static void destroy() {
        CACHE_CCLIENT.values().forEach(MongoClient::close);
    }

    public static void destroy(String id) {
        MongoClient mongoClient = CACHE_CCLIENT.remove(id);
        if (Objects.nonNull(mongoClient)) {
            mongoClient.close();
        }
    }

    public static MongoClient create(String connectionString, DbProperty property) {
        MongoClient mongoClient;
        if (StringUtils.isNotBlank(property.getId())) {
            mongoClient = CACHE_CCLIENT.get(property.getId());
            if (Objects.isNull(mongoClient)) {
                synchronized (property.getId()) {
                    mongoClient = CACHE_CCLIENT.get(property.getId());
                    if (Objects.isNull(mongoClient)) {
                        ConnectionString connectionSetting = new ConnectionString(connectionString);
                        mongoClient = MongoClients.create(
                                MongoClientSettings.builder()
                                        .applyConnectionString(connectionSetting)
                                        .applyToConnectionPoolSettings(builder -> builder.maxSize(property.getMaxConn()))
                                        .build()
                                , null);
                        CACHE_CCLIENT.put(property.getId(), mongoClient);
                    }
                }
            }
        } else {
            ConnectionString connectionSetting = new ConnectionString(connectionString);
            mongoClient = MongoClients.create(
                    MongoClientSettings.builder()
                            .applyConnectionString(connectionSetting)
                            .applyToConnectionPoolSettings(builder -> builder.maxSize(property.getMaxConn()))
                            .build()
                    , null);
        }
        return mongoClient;
    }
}
